#pragma once

#include <string>
#include <vector>
#include <functional>

#include "CameraDef.h"
#include "opencv2/opencv.hpp"

#if defined(_MSC_VER)
#define interface_class __declspec(novtable)
#else
#define interface_class __attribute__((no_vtable))
#endif

namespace XCamera
{	
	// 抽象相机接口
	class interface_class ICamera
	{
	public:
		virtual ~ICamera() = default;
		virtual bool Create(std::string camInfo="");			// 创建相关资源:camInfo，可以是相机全名，序列号，或者用户定义名称

		virtual int OpenDevice();		// 打开相机
		virtual int CloseDevice();		// 关闭相机
		virtual bool IsOpened();		// 相机是否打开
		virtual bool IsConnected();		// 是否处于连接状态

		virtual int Grab();				// 连续采集
		virtual int Snap(int count = 1);	// 采集指定的帧数
		virtual int Freeze();			// 冻结
		virtual int Stop();				// 停止采集

		virtual int getImageBuffer(cv::Mat& outMat, int ms);	// 同步采集方式，获取当前采集帧
		virtual int readBuffer(cv::Mat &img);		// 读取图像帧

		virtual bool IsGrabbing();		// 相机是否正在采集

		virtual int SetTriggerMode(int trigMode);
		virtual int GetTriggerMode(int *trigMode);

		virtual int SetTriggerSource(TriggerSource trigSource);	// 设置触发源
		virtual int GetTriggerSource(int *trigSource);		// 获取触发源

		virtual int ExecuteSoftwareTrigger();			// 软触发一次

		virtual int SetExposureTime(double exposureTime);	// 设置曝光时间
		virtual int GetExposureTime(double *exposureTime);	// 获取曝光时间

		virtual int SetFrameRate(double frameRate);			// 设置帧率
		virtual int GetFrameRate(double *frameRate);			// 获取帧率

		virtual void EnableFrameRate(bool enable);
		virtual bool IsEnableFrameRate();

		virtual int SetGain(double gain);		// 设置增益
		virtual int GetGain(double *gain);		// 获取增益

		// 注册通用采集回调函数
		virtual void RegisterContext(void *context);
		virtual void RegisterCallback(CameraCallback grabCallback);
		virtual void RegisterCallback(XGrabCallback grabCallback);
		virtual void UnRegisterCallback();

		// 注册日志回调函数
		virtual void RegisterLogsCallback(LogsCallback logsFun);
		virtual void RegisterLogsWnd(void *context);
		virtual void UnRegisterLogs();

		// 获取相机信息
		virtual std::string GetXModelName();
		virtual std::string GetXUserName();
		virtual std::string GetXSerialNum();
		// 加载配置文件:或者加载保存在相机中配置，一般有几个通道
		virtual bool Load(std::string profile);
		virtual bool Save(std::string profile);

		// 临时版本
		// 相机输出IO信号：duration为时间周期，invert表示是否采用翻转信号
		// 海康部分相机不支持直接输出，采用信号翻转的方式输出一个信号
		virtual void DigitalOutput(int duration, int lineSelector, bool enableInvert=false);

		// 返回最后一条错误信息
		virtual std::string GetLastErr();
	};

	// 导出相机创建函数：new
	using CreateCameraFun = ICamera* (*)();
	// 相机供应商
	using VendorFun = std::string(*)();


	//extern "C"
	//{
	//	CAMERA_DLL_API ICamera* __cdecl CreateCamera();
	//	CAMERA_DLL_API void __cdecl CameraVendor(string &vendor);
	//	// 枚举相机序列号
	//	CAMERA_DLL_API void __cdecl EnumSerialNums(vector<string> &serialNums);
	//	//  获取相机sdk得版本号
	//	CAMERA_DLL_API void __cdecl GetSDKVersion(string &sdkVer);
	//}
}